﻿using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Mvc;
using System.Xml;
using BrnMall.Core;
using BrnMall.Manager.Domain.Distribution;
using BrnMall.Manager.Manager.Distribution;
using BrnMall.Manager.Manager.Store;
using BrnMall.Manager.Manager.WeApp;
using BrnMall.Services;
using BrnMall.Web.Framework;
using BrnMall.Web.StoreAdmin.Util;
using Tencent;


namespace BrnMall.Web.StoreAdmin.Controllers
{
    public class WeChatController : BaseStoreAdminController
    {
        /// <summary>
        /// 微信企业打款
        /// </summary>
        /// <returns></returns>
        /// <param name="brsn">提现记录订单号</param>
        /// <param name="sendUserId">发放人</param>
        public ActionResult Transfer(string brsn, int sendUserId)
        {
            try
            {
                var brRequest = BrokerageManager.GetBrokerageRequestByBrsn(brsn);

                if (brRequest == null || brRequest.Status != 1)
                {
                    LogUtil.WriteLog($"提现记录不存在或者未审核{brsn}");
                    return new EmptyResult();
                }
                if (brRequest.PayStatus == 1) return new EmptyResult();
                var toUser = Users.GetPartUserById(brRequest.UserId);
                //var storeWxConfig = StoreWxAppManager.GetStoreDefaultWxAppById(brRequest.StoreId,toUser.WeAppId);
                //if (storeWxConfig == null) { LogUtil.WriteLog($"企业打款，未找到店铺配置或者店铺{brRequest.StoreId}"); return new EmptyResult(); }
                //if(string.IsNullOrEmpty(storeWxConfig.MchId)||string.IsNullOrEmpty(storeWxConfig.MchKey))
                //    return PromptView("商户支付账号和秘钥配置错误");
                //if(string.IsNullOrEmpty(storeWxConfig.CertPath))
                //    return PromptView("请上传微信支付证书文件");
                //付款金额
                string totalFee = ((int)(brRequest.Amount * 100)).ToString();
                var appid = string.Empty;
                var mchId = string.Empty;
                var mchKey = string.Empty;
                var certPath = string.Empty;

                if (toUser.StoreAppId != 0)
                {
                    var paysetting = StoreApplicationManager.GetStoreApplicationPaySetting(toUser.StoreAppId);
                    var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(toUser.StoreAppId);
                    if (paysetting == null || auth == null)
                    {
                        Trace.TraceWarning("小程序平台授权失败,尝试采用手动打包的默认配置");
                        var defaultStoreWeApp = StoreWxAppManager.GetStoreDefaultWxAppById(toUser.RegisterFromStoreId, 0);
                        if (defaultStoreWeApp == null)
                            throw new Exception("尝试获取授权信息失败");
                        appid = defaultStoreWeApp.WeAppId;
                        mchId = defaultStoreWeApp.MchId;
                        mchKey = defaultStoreWeApp.MchKey;
                        certPath = defaultStoreWeApp.CertPath;
                    }
                    else
                    {

                        appid = auth.Authorizer_Appid;
                        mchId = paysetting.MchId;
                        mchKey = paysetting.MchKey;
                        certPath = paysetting.CertPath;
                    }


                }
                else if (toUser.WeAppId != 0)
                {
                    var wxapp = StoreWxAppManager.GetStoreDefaultWxAppById(brRequest.StoreId, toUser.WeAppId);

                    if (string.IsNullOrEmpty(wxapp?.WeAppId) || string.IsNullOrEmpty(wxapp.WeAppSecret)
                        || string.IsNullOrEmpty(wxapp.MchId) || string.IsNullOrEmpty(wxapp.MchKey)
                        || string.IsNullOrEmpty(wxapp.CertPath))
                        throw new Exception("请登录商户后台设置小程序AppID,AppSecret,MchID,MchKey");
                    appid = wxapp.WeAppId;
                    mchId = wxapp.MchId;
                    mchKey = wxapp.MchKey;
                    certPath = wxapp.CertPath;
                }
                if (string.IsNullOrEmpty(appid))
                    throw new Exception("小程序appid配置为空");
                if (string.IsNullOrEmpty(mchId))
                    throw new Exception("支付商户号配置为空");
                if (string.IsNullOrEmpty(mchKey))
                    throw new Exception("支付秘钥配置为空");
                if (string.IsNullOrEmpty(certPath))
                    throw new Exception("支付证书配置为空");
                //时间戳 
                string timeStamp = TenpayUtil.getTimestamp();
                //随机字符串 
                string nonceStr = TenpayUtil.getNoncestr();


                //创建支付应答对象
                RequestHandler packageReqHandler = new RequestHandler(System.Web.HttpContext.Current);
                packageReqHandler.setParameter("mch_appid", appid);
                packageReqHandler.setParameter("mchid", mchId);
                packageReqHandler.setParameter("nonce_str", nonceStr);
                packageReqHandler.setParameter("partner_trade_no", brRequest.Brsn);
                packageReqHandler.setParameter("openid", brRequest.RequestOpenId);
                packageReqHandler.setParameter("check_name", "NO_CHECK");
                packageReqHandler.setParameter("amount", totalFee);
                packageReqHandler.setParameter("desc", "分销商佣金发放");
                packageReqHandler.setParameter("spbill_create_ip", Request.UserHostAddress);
                packageReqHandler.setParameter("re_user_name", "");
                string sign = packageReqHandler.CreateMd5Sign("key", mchKey);
                LogUtil.WriteLog("WeiPay 页面  sign：" + sign);
                packageReqHandler.setParameter("sign", sign);
                string data = packageReqHandler.parseXML();
                LogUtil.WriteLog("WeiPay 页面  package（XML）：" + data);
                var fileDir = IOHelper.GetMapPath($"/upload/store/{brRequest.StoreId}/cert/");
                if (!Directory.Exists(fileDir))
                    Directory.CreateDirectory(fileDir);
                var fileUrl = $"{fileDir}{certPath}";
                var url =
                    $"{BMAConfig.MallConfig.ImageCDN}/upload/store/{brRequest.StoreId}/cert/{certPath}";
                LogUtil.WriteLog(fileUrl);
                LogUtil.WriteLog(url);
                if (!System.IO.File.Exists(fileUrl))
                {
                    var client = new WebClient();
                    client.DownloadFile(url, fileUrl);
                }
                LogUtil.WriteLog("开始发送请求");
                var resultXML = HttpUtil.Post(new Uri("https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"), data, mchId, fileUrl);
                LogUtil.WriteLog($"请求结果:{resultXML}");
                var resHandler = new ResponseHandler(resultXML);
                //SUCCESS/FAIL此字段是通信标识，非交易标识，交易是否成功需要查
                string return_code = resHandler.getParameter("return_code");
                //业务结果 SUCCESS/FAIL
                string result_code = resHandler.getParameter("result_code");
                string err_code_des = resHandler.getParameter("err_code_des") ?? "";
                //商户系统的订单号，与请求一致。
                string out_trade_no = resHandler.getParameter("partner_trade_no");
                //企业付款成功，返回的微信订单号
                string payment_no = resHandler.getParameter("payment_no");

                //支付成功
                if (!out_trade_no.Equals("") && return_code.Equals("SUCCESS") && result_code.Equals("SUCCESS"))
                {
                    var sendUser = Users.GetPartUserById(sendUserId);
                    LogUtil.WriteLog("企业打款页面  支付成功，支付信息：商家订单号：" + out_trade_no + "、支付金额(分)：" + totalFee);
                    var record = new BrokerageSendRecord
                    {
                        BRId = brRequest.Id,
                        SendAmount = brRequest.Amount,
                        SendTime = DateTime.Now,
                        SendUserId = sendUserId,
                        SendUserName = sendUser.NickName,
                        Status = 1,
                        TradeNo = payment_no,
                        TradeType = 0
                    };
                    var brsid = BrokerageManager.AddBrokerageSendRecord(record);
                    if (brsid <= 0) return PromptView("添加打款记录错误");
                    brRequest.PayStatus = 1;
                    brRequest.SendTime = DateTime.Now;
                    BrokerageManager.UpdateBrokerageRequest(brRequest);

                    DistributorManager.AppendDistributorRequestBalance(brRequest.UserId, record.SendAmount);
                    return PromptView("发放佣金成功");
                }

                return PromptView($"发放佣金错误系统错误:{result_code}{err_code_des}");
            }
            catch (Exception e)
            {
                LogUtil.WriteLog(e.Message);
                LogUtil.WriteLog(e.Source);
                LogUtil.WriteLog("企业打款发生错误");
                return PromptView(e.Message);
            }
        }

    }
}